package MyPackage;
import java.io.*;
import java.util.Scanner;
import java.util.Date;

public class Model {

	public String dir="C:\\";
	public String arg1;
	public String arg2;
	public int numArg=0;
	
	public String printDir(){
		Directory myDir=new Directory();
		String absPath=dir;
		if(numArg==1) absPath=this.getAbsPath(dir, arg1); 
		//if(numArg>1)// throw exception //bad format of command; 
		return myDir.getDirContent(absPath);	
	}
	
	public String tree(){
		PrintTree myDir = new PrintTree();
		String absPath=dir;
		if(numArg==1) absPath=this.getAbsPath(dir, arg1); 
		//if(numArg>1)// throw exception //bad format of command; 
		return myDir.getTreeDir(absPath);
	}
	
	public String find(){
		Find myFind=new Find();
		String mask;
		String absPath=dir;
		//if(numArg>2)// throw exception //bad format of command; 
		if(numArg==1) mask=arg1; 
		else {
			absPath=this.getAbsPath(dir, arg1);
			mask=arg2;
		}
		return myFind.find(absPath, mask);
	}
	
	public boolean copy(){
		Copy myCopy=new Copy();
		String absPath1=dir;
		String absPath2=dir;
		if(numArg==2) {
			absPath1=this.getAbsPath(dir, arg1);
			absPath2=this.getAbsPath(dir, arg2);
		}
		//else  throw exception //bad format of command; 
		return myCopy.copy(absPath1, absPath2);
	}
	
	public boolean move(){
		Move myMove=new Move();
		String absPath1=dir;
		String absPath2=dir;
		if(numArg==2) {
			absPath1=this.getAbsPath(dir, arg1);
			absPath2=this.getAbsPath(dir, arg2);
		}
		//else  throw exception //bad format of command; 
		return myMove.move(absPath1, absPath2);
	}
	
	public boolean del(){
		Del myDel=new Del();
		String absPath=dir;
		if(numArg==1) absPath=this.getAbsPath(dir, arg1);
		//else  throw exception //bad format of command; 
		return myDel.del(absPath);
	}
	
	public String cd(){
		Cd myCd=new Cd();
		String absPath=dir;
		if(numArg==1) return myCd.cd(dir, arg1);
		else return dir; //  throw exception //bad format of command;
	}
	
	public boolean mkDir(){
		MkDir myMkDir=new MkDir();
		String absPath=dir;
		if(numArg==1) absPath=this.getAbsPath(dir, arg1);
		//else  throw exception //bad format of command; 
		return myMkDir.mkdir(absPath);
	}
		
	
	private String getAbsPath(String directory, String arg){
		//translate name of file and work directory in absolute directory 
		File fArg=new File(arg);
		String absDir;
		if(!fArg.exists())	absDir=directory+File.separator+arg; else absDir=arg;
		return absDir;
	}
	

	public class Directory{
		
		public String getDirContent(String directory){
			String printString="";
			
		        File f=new File(directory);
		        if(!f.exists()){
		        	System.out.println("Not found directory "+f.toString());
		        }
		        else{
		        	String[] dirList=f.list();
		            int k=0;
		            String[] fileList=new String[dirList.length];
		            for(int i=0;i<dirList.length;i++){
		                    File f1=new File(directory+File.separator+dirList[i]);
		                    if(!f1.isFile()) printString+="DIR "+dirList[i]+"\n";
		                    else{
		                            fileList[k]=dirList[i];
		                            k++;
		                    }
		            }
		            for(int i=0;i<k;i++){
		            	printString+=fileList[i]+"\n";
		            }
		        }
		        return printString;
		    }

	}
	
	public class PrintTree{
			
			 private String printString;
			 			
        public String getTreeDir(String directory){
                File f=new File(directory);
                if(!f.exists()){
                        System.out.println("Not found directory "+f.toString());
                }
                else{
                		printString=directory+"\n";
                		insertedTree(directory,0);
                }
                return printString;
        }
        
        private void printNameDir(String directory,String dirList, int y){
                File f1=new File(directory+File.separator+dirList);
                if(!f1.isFile()){
                        for(int j=0; j<y;j++ ) printString+="  ";
                        printString+="+ "+dirList+"\n";
                        }
                else {
                	for(int j=0; j<y;j++ ) printString+="  "; 
                	printString+="  "+dirList+"\n";
                }
        }
                      
        private void insertedTree(String directory,int y){
                // y - level inserted. Start from 0. Increase.
                File f=new File(directory);
                String[] dirList=f.list();
                for(int i=0;i<dirList.length;i++){
                        printNameDir(directory,dirList[i],y);
                        // if dirList[i] is directory then call printTree for dirList[i]
                        String absDir=directory+File.separator+dirList[i];
                        File f1=new File(absDir);
                        if(!f1.isFile()) insertedTree(absDir,y+1);
                }
        }
			
		}
	
	public class Find{
		
		private String printString;
		
		public String find(String directory, String mask){
			printString="";
			printString=searchInTreeRecursion(directory, mask);
			return printString;
		}

		private String searchInTreeRecursion(String directory, String mask){
			//Method runs searchInDir only in folder - 'dir' and run itself in all include folders
			File f=new File(directory);
			if(!f.exists()) System.out.println("Not found directory "+f.toString());
			else{
		
			searchInDir(directory,mask);
			String[] dirList=f.list();
			for(int i=0;i<dirList.length;i++){
				String absDir=directory+File.separator+dirList[i];
				File f1=new File(absDir);
				if(!f1.isFile()) searchInTreeRecursion(absDir,mask);
				}
			}
			return printString;
		}

		public void searchInDir(String directory, String mask){
			File f=new File(directory);
			if(!f.exists()) System.out.println("Not found directory "+f.toString());
			else{
			
			
			String[] dirList=f.list();
			String[] arrayMask;
			
			if(mask.contains("*")) mask=mask.replace("*", "`");
			
			if(mask.contains("`")){
					arrayMask = mask.split("`");
			
			for(int i=0;i<dirList.length;i++) {
				String sDirList=dirList[i];
				int k=0;
				while(sDirList.length()>0 && k<arrayMask.length){
					if(sDirList.startsWith(arrayMask[k])){
						for(int r=0; r<arrayMask[k].length();r++) sDirList=cutDir(sDirList);
						k++;
					}
					else{ 
						sDirList=cutDir(sDirList);
					}
				}
				if(k>=arrayMask.length)	printName(directory+File.separator+dirList[i]);
			}
			
			}
			else{
				for(int i=0;i<dirList.length;i++) {
					if(dirList[i].equals(mask))	printName(directory+File.separator+dirList[i]);
				}
			}
			
			}
		}

		private String cutDir(String directory){
			int ld=directory.length();
			char[] newDir=new char[ld-1];
			directory.getChars(1, ld, newDir, 0);
			String sNewDir=newDir.toString();
			sNewDir=sNewDir.copyValueOf(newDir);
	return sNewDir;
	}
		
		private void printName(String dirName){
			File f1=new File(dirName);
			Date date=new Date(f1.lastModified());
			printString+=f1.getName()+" \t"+date+" "+f1.getPath()+"\n";
			//System.out.println(f1.getName()+" \t"+date+" "+f1.getPath());
		}
	}
	
	public class Copy{
		
		public boolean copy(String sFileFrom, String sFileTo){
			boolean result=false;
			
			File fileFrom=new File(sFileFrom);
			if(!fileFrom.exists()) {
				System.out.println("Not found file "+fileFrom.toString());
			}
			else{
					//copy
					try{
					File fileTo=new File(sFileTo);
					if(fileTo.exists()){
						System.out.println("File "+fileTo.toString()+" exists. \nRewrite? (y/n)");
						Scanner inp=new Scanner(System.in);
						   	if(inp.nextLine().toString().equals("y")){
						   		Del myDel=new Del();
						   		if(myDel.delFile(sFileTo)) result=copy(sFileFrom,sFileTo);
						  	}
						   	else System.out.println("Operation canceled.");
					}
					else{
					InputStream in = new FileInputStream(fileFrom);
					OutputStream out = new FileOutputStream(fileTo);

					  byte[] buf = new byte[1024];
					  int len;
					  while ((len = in.read(buf)) > 0){
					  out.write(buf, 0, len);
					  }
					  in.close();
					  out.close();
					  System.out.println("File copied.");
					  result= true;
					}
					}
					
					catch(FileNotFoundException ex){
						  System.out.println(ex.getMessage() + " in the specified directory.");
						  System.out.println("Do you want to create a new directory? (y/n)");
						  Scanner inp=new Scanner(System.in);
						   	if(inp.nextLine().toString().equals("y")){
						   		File fileTo=new File(sFileTo);
						   		MkDir myMkDir=new MkDir();
						  		if(myMkDir.mkdir(fileTo.getParent())) {
						  			if(copy(sFileFrom,sFileTo)) result= true;
						  		}
						  	}
						  	else System.out.println("Operation canceled.");
					}
					catch(IOException e){
						  System.out.println(e.getMessage());
						  result= false;
					}
			}
			return result;
		} 

	}
	
	public class Move{
		
		public boolean move(String fileFrom, String fileTo){
			Copy myCopy=new Copy();
			if(myCopy.copy(fileFrom,fileTo)){
				Del myDel=new Del();
				if(myDel.delFile(fileFrom)) return true; else return false;
			}
			else{
				return false;
			}
		}
			
	}
	
	public class Del{

	public boolean delFile(String directory){
			File delDir=new File(directory);
			if(delDir.delete()) {
				System.out.println("Directory '"+directory+"' deleted.");
				return true;
			}
				else{ 
					System.out.println("Error. Directory doesn't delete.");
					return false;
			}
		}

	public boolean del(String directory){
			// Deleted all tree directory
			boolean result=false;
			File delDir=new File(directory);
			
		if(delDir.exists()) {
				
			if(delDir.list().length>0){
				System.out.println("All files will be deleted!\nYou sure, that you want delete all files? (y/n)");
				Scanner inp=new Scanner(System.in);
			   	if(inp.nextLine().toString().equals("y")) result= delAll(directory); else System.out.println("Operation canceled.");
			} else result=delFile(directory);
		} else System.out.println("Not found "+directory+"\nDirectory doesn't delete.");

	return result;
	}
		
	public boolean delAll(String directory){
            // Deleted all tree directory
		boolean result=false;
            File delDir=new File(directory);
            
    if(delDir.exists()) {
                    
            if(delDir.list().length>0){
                    String[] delList=delDir.list();
                    boolean flag=true;
                    for(int i=0; i<delList.length;i++){
                            String sFileFromList=directory+File.separator+delList[i];
                            File fileFromList= new File(sFileFromList);
                            if(fileFromList.isDirectory()){
                                    if(!delAll(sFileFromList)) flag=false;
                            }
                            else{
                                    if(!delFile(sFileFromList)) {
                                            flag= false;
                                            break;
                                    }
                            }
                    }
                    // flag = true if all files were deleted from directory
                    if(flag=true) result=delFile(directory);
            }
            else result=delFile(directory);
    }
    else{ 
            System.out.println("Not found "+directory+"\nDirectory doesn't delete.");
    }
    
    return result;
    }

}

	public class Cd{
		
		public String cd(String directory, String newDir){
			File fDir=new File(directory);
			
			if(!fDir.exists()) System.out.println("Not found "+directory);
			else{
				if(newDir.equals("..")){
					// Check if work directory is root.
					boolean dirIsRoot=false;
					File[] arrayRoots=fDir.listRoots();
					for(int i=0; i<arrayRoots.length;i++){
						if(arrayRoots[i].equals(fDir)) dirIsRoot=true;
					} 
					if(!dirIsRoot) directory=fDir.getParent(); else  System.out.println(directory+" is root! Impossible command.");
				}
				else{
					newDir=getAbsPath(directory, newDir);
					File fNewDir=new File(newDir);
					if(!fNewDir.exists()) System.out.println("Not found "+newDir);
					else directory = newDir;
				}
			}
			return directory;
		}
		
	}
	
	public class MkDir{
		
		public boolean mkdir(String sNewDir){
			File newDir=new File(sNewDir);
			
			if(newDir.mkdirs())  {
				System.out.println("Directory '"+sNewDir+"' create.");
				return true;
				}
			else{				
				System.out.println("Error. Directory doesn't create.");
				return false;
			}
		}
	}

	
}

